package com.neu.envprotection.admin.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.neu.envprotection.admin.cache.VerifyCodeManager;
import com.neu.envprotection.admin.dto.resp.GetVerifyCodeRespDto;
import com.neu.envprotection.admin.service.UserService;
import com.neu.envprotection.common.auth.JwtUtils;
import com.neu.envprotection.common.auth.UserHolder;
import com.neu.envprotection.common.constant.ErrorCodeEnum;
import com.neu.envprotection.common.constant.SystemConfigConsts;
import com.neu.envprotection.common.constant.UserRoleEnum;
import com.neu.envprotection.common.resp.PageRespDto;
import com.neu.envprotection.common.resp.RestResp;
import com.neu.envprotection.admin.config.exception.BusinessException;
import com.neu.envprotection.admin.dao.entity.User;
import com.neu.envprotection.admin.dao.mapper.UserMapper;
import com.neu.envprotection.admin.dto.req.GetGridManReqTto;
import com.neu.envprotection.admin.dto.req.GetSupervisorReqDto;
import com.neu.envprotection.admin.dto.req.UserLoginReqDto;
import com.neu.envprotection.admin.dto.req.UserRegisterReqDto;
import com.neu.envprotection.admin.dto.resp.GetGridManRespDto;
import com.neu.envprotection.admin.dto.resp.GetSupervisorRespDto;
import com.neu.envprotection.admin.dto.resp.UserLoginRespDto;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 管理员业务模块
 */
@Service
@RequiredArgsConstructor
@Slf4j
@Transactional
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;

    private final VerifyCodeManager verifyCodeManager;

    @Override
    public RestResp<Void> register(UserRegisterReqDto dto) {
        if(!verifyCodeManager.imgVerifyCodeOk(dto.getSessionId(),dto.getVerifyCode())){
            throw new BusinessException(ErrorCodeEnum.USER_VERIFY_CODE_ERROR);
        }

        User user = new User();
        BeanUtils.copyProperties(dto,user);

        QueryWrapper<User> userSelectPhone = new QueryWrapper<>();
        userSelectPhone.eq("phone_number",dto.getTelephone());
        if(userMapper.selectOne(userSelectPhone)!=null){
            throw new BusinessException(ErrorCodeEnum.PHONE_ALREADY_EXIST);
        }

        QueryWrapper<User> userSelectName = new QueryWrapper<>();
        userSelectName.eq("name",dto.getName());

        if(userMapper.selectOne(userSelectName)!=null){
            throw new BusinessException(ErrorCodeEnum.NAME_ALREADY_EXIST);
        }


        user.setIsDelete(1);
        user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes(StandardCharsets.UTF_8)));
        user.setCreateTime(LocalDateTime.now());
        user.setPhoneNumber(dto.getTelephone());
        user.setUserType(dto.getUserType());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.insert(user);
        return RestResp.ok();
    }

    @Override
    public RestResp<UserLoginRespDto> login(UserLoginReqDto dto) {
        // 查询用户信息
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", dto.getName())
                .last("limit 1");
        User user = userMapper.selectOne(queryWrapper);

        if (Objects.isNull(user)) {
            // 用户不存在
            throw new BusinessException(ErrorCodeEnum.USER_ACCOUNT_NOT_EXIST);
        }

        // 判断密码是否正确
        if (!Objects.equals(user.getPassword()
                , DigestUtils.md5DigestAsHex(dto.getPassword().getBytes(StandardCharsets.UTF_8)))) {
            // 密码错误
            throw new BusinessException(ErrorCodeEnum.USER_PASSWORD_ERROR);
        }

        System.out.println("用户id"+ UserHolder.getUserId());

        // 登录成功，生成JWT并返回
        return RestResp.ok(UserLoginRespDto.builder()
                .token(JwtUtils.generateToken(user.getId(), SystemConfigConsts.ENV_FRONT_KEY))
                .uid(user.getId())
                .name(user.getName())
                .userType(user.getUserType())
                .build());
    }

    @Override
    public RestResp<User> getUser(Integer id) {
        User ans = userMapper.selectById(id);
        return RestResp.ok(ans);
    }

    @Override
    public RestResp<User> getUserById(Integer id) {
        return RestResp.ok(userMapper.selectById(id));
    }

    @Override
    public RestResp<PageRespDto<GetSupervisorRespDto>> queryPageSupervisor(GetSupervisorReqDto dto) {

        Page<User> page = new Page<>();
        page.setCurrent(dto.getPageNum());
        page.setSize(dto.getPageSize());

        dto.setUserType(UserRoleEnum.MONITOR.getCode());
        List<User> userList = userMapper.searchUsers(page,dto);
        List<GetSupervisorRespDto> respDtoList = new ArrayList<>();
        for (int i = 0; i < userList.size(); i++) {
            GetSupervisorRespDto temp = new GetSupervisorRespDto();
            BeanUtils.copyProperties(userList.get(i),temp);
            temp.setBirthDay(userList.get(i).getBirthDay().toLocalDate());
            temp.setTelephone(userList.get(i).getPhoneNumber());
            temp.setUid(userList.get(i).getId());
            respDtoList.add(temp);
        }
        PageRespDto<GetSupervisorRespDto> res = PageRespDto.of(
                dto.getPageNum(),dto.getPageSize(),page.getTotal(),respDtoList
        );
        return RestResp.ok(res);
    }

    @Override
    public RestResp<PageRespDto<GetGridManRespDto>> queryGridMan(GetGridManReqTto dto) {

        Page<User> page = new Page<>();
        page.setCurrent(dto.getPageNum());
        page.setSize(dto.getPageSize());

        dto.setUserType(UserRoleEnum.GRIDMAN.getCode());
        List<GetGridManRespDto> list = userMapper.searchGrids(page,dto);

        PageRespDto<GetGridManRespDto> res =
                PageRespDto.of(dto.getPageNum(),dto.getPageSize(),page.getTotal(),list);

        return RestResp.ok(res);
    }

    @Override
    public RestResp<List<GetGridManRespDto>> getAllGridMan() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_type",UserRoleEnum.GRIDMAN.getCode());
        List<User> users = userMapper.selectList(wrapper);
        List<GetGridManRespDto> list = new ArrayList<>();
        for (int i = 0; i < users.size(); i++) {
            GetGridManRespDto temp = new GetGridManRespDto();
            BeanUtils.copyProperties(users.get(i),temp);
            temp.setUid(users.get(i).getId());
            list.add(temp);
        }

        return RestResp.ok(list);
    }

    @Override
    public RestResp<Void> updateById(User user) {
        userMapper.updateById(user);
        return RestResp.ok();
    }

    @Override
    public RestResp<GetVerifyCodeRespDto> getVerifyCode() {
        GetVerifyCodeRespDto res = new GetVerifyCodeRespDto();
        res.setVerifyCode(verifyCodeManager.generateRandomVerifyCode(4));
        res.setSessionId(IdWorker.get32UUID());

        verifyCodeManager.storeVerifyCode(res);
        return RestResp.ok(res);
    }

    @Override
    public RestResp<Void> storeVerifyCode(GetVerifyCodeRespDto dto) {
        verifyCodeManager.storeVerifyCode(dto);
        return RestResp.ok();
    }

    @Override
    public RestResp<Void> deleteUser(Integer uid) {
        User user = userMapper.selectById(uid);
        user.setIsDelete(0);
        userMapper.updateById(user);
        return RestResp.ok();
    }


}
